using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
using DrawTools.Properties;

namespace DrawTools.Editor.CanvasFigures
{
  /// <summary>
  ///   Polygon graphic object
  /// </summary>
  public class CanvasPolyline : CanvasArrow
  {
    private readonly List<Point> _pointArray; // list of points
    private Cursor _handleCursor;

    public override int HandlesCount
    {
      get { return _pointArray.Count; }
    }

    public CanvasPolyline()
    {
      _pointArray = new List<Point>();

      LoadCursor();
    }

    public CanvasPolyline(int x1, int y1, int x2, int y2)
    {
      _pointArray = new List<Point>
      {
        new Point(x1, y1),
        new Point(x2, y2)
      };

      LoadCursor();
    }

    public override void Draw(Graphics graphics)
    {
      graphics.SmoothingMode = SmoothingMode.AntiAlias;

      using (var pen = CreateBorderPen())
      {
        graphics.DrawCurve(pen, _pointArray.ToArray(), 0.7f);
      }
    }

    public override Cursor GetHandleCursor(int handleNumber)
    {
      return _handleCursor;
    }

    public override void MoveHandleTo(Point point, int handleNumber, bool shiftPressed)
    {
      if (handleNumber < 1)
        handleNumber = 1;

      if (handleNumber > _pointArray.Count)
        handleNumber = _pointArray.Count;

      _pointArray[handleNumber - 1] = point;

      Invalidate();
    }

    public override void Move(int deltaX, int deltaY)
    {
      for (int i = 0; i < _pointArray.Count; i++)
      {
        var point = _pointArray[i];
        _pointArray[i] = new Point(point.X + deltaX, point.Y + deltaY);
      }

      Invalidate();
    }

    public void AddPoint(Point point)
    {
      _pointArray.Add(point);
    }

    /// <summary>
    ///   Get handle point by 1-based number
    /// </summary>
    /// <param name="handleNumber"></param>
    /// <returns></returns>
    protected override Point GetHandle(int handleNumber)
    {
      if (handleNumber < 1)
        handleNumber = 1;

      if (handleNumber > _pointArray.Count)
        handleNumber = _pointArray.Count;

      return _pointArray[handleNumber - 1];
    }

    /// <summary>
    ///   Create graphic object used for hit test
    /// </summary>
    protected override void CreateObjects()
    {
      if (AreaPath != null)
        return;

      // Create closed path which contains all polygon vertexes
      AreaPath = new GraphicsPath();

      int x1 = 0, y1 = 0; // previous point

      IEnumerator enumerator = _pointArray.GetEnumerator();

      if (enumerator.MoveNext())
      {
        x1 = ((Point)enumerator.Current).X;
        y1 = ((Point)enumerator.Current).Y;
      }

      while (enumerator.MoveNext())
      {
        int x2 = ((Point)enumerator.Current).X; // current point
        int y2 = ((Point)enumerator.Current).Y; // current point

        AreaPath.AddLine(x1, y1, x2, y2);

        x1 = x2;
        y1 = y2;
      }

      AreaPath.CloseFigure();

      // Create region from the path
      AreaRegion = new Region(AreaPath);
    }

    private void LoadCursor()
    {
      //_handleCursor = new Cursor(GetType(), "PolyHandle.cur");
      _handleCursor = new Cursor(new MemoryStream(Resources.PolyHandle));
    }
  }
}